package com.sambo.inspection;

import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.support.multidex.MultiDexApplication;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.google.gson.JsonElement;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.cache.CacheEntity;
import com.lzy.okgo.cache.CacheMode;
import com.lzy.okgo.https.HttpsUtils;
import com.lzy.okgo.interceptor.HttpLoggingInterceptor;
import com.lzy.okgo.model.HttpParams;
import com.sambo.inspection.activity.LoginActivity;
import com.sambo.inspection.activity.MainActivity;
import com.sambo.inspection.activity.support.ActivityCache;
import com.sambo.inspection.bean.GlobleBean;
import com.sambo.inspection.bean.SaveTrajectoryBean;
import com.sambo.inspection.http.HttpClient;
import com.sambo.inspection.http.HttpResponseHandler;
import com.sambo.inspection.http.Urls;
import com.sambo.inspection.receiver.NotifyMessageReceiver;
import com.sambo.inspection.util.LogUtil;
import com.tencent.bugly.crashreport.CrashReport;
import com.xiaomi.channel.commonutils.logger.LoggerInterface;
import com.xiaomi.mipush.sdk.Logger;
import com.xiaomi.mipush.sdk.MiPushClient;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;

import okhttp3.OkHttpClient;

/**
 * 初始化全局变量以及一些三方库
 */
public class InspectionApplication extends MultiDexApplication {

    public static final String TAG = "MiPush";

    // 小米推送APP_ID
    private static final String MIPUSH_APP_ID = "2882303761517953039";
    // 小米推送APP_KEY
    private static final String MIPUSH_APP_KEY = "5221795397039";

    private static final String BUGLY_APP_ID = "d0e40476d2";

    private static InspectionApplication mInstance;
    private static AMapLocation sMapLocation;

    private static PushHandler sHandler = null;
    private static MainActivity sMainActivity = null;

    private static String sPushRegID = null;

    private static long sInspectionID = 0;

    private boolean isPushServiceSetupSuccess = false;
    private boolean isLocationSetup = false;

    //声明AMapLocationClient类对象
    public AMapLocationClient mLocationClient = null;
    public AMapLocationClientOption mLocationOption = null;
    //声明定位回调监听器
    public AMapLocationListener mLocationListener = new AMapLocationListener() {
        @Override
        public void onLocationChanged(AMapLocation aMapLocation) {
            if (aMapLocation != null) {
                if (aMapLocation.getErrorCode() == 0) {
                    LogUtil.e("获取到当前坐标: Latitude = " + aMapLocation.getLatitude() + ", Longitude = " + aMapLocation.getLongitude());
                    sMapLocation = aMapLocation;
                    // 上报定位信息
                    uploadLocation(aMapLocation);
                } else {
                    LogUtil.e("定位失败：" + aMapLocation.getErrorInfo());
                }
            }

        }
    };

    @Override
    public void onCreate() {
        super.onCreate();

        mInstance = this;
        // 初始化bugly
        CrashReport.initCrashReport(mInstance, BUGLY_APP_ID, true);

        initOkGo();

        initPushService();

        initLocationService();
    }

    public static InspectionApplication getInstance() {
        return mInstance;
    }

    private void initPushService() {
        // 注册push服务，注册成功后会向PushMessageReceiver发送广播
        // 可以从DemoMessageReceiver的onCommandResult方法中MiPushCommandMessage对象参数中获取注册信息
        if (shouldInit()) {
            MiPushClient.registerPush(this, MIPUSH_APP_ID, MIPUSH_APP_KEY);
        }

        LoggerInterface newLogger = new LoggerInterface() {

            @Override
            public void setTag(String tag) {
                // ignore
            }

            @Override
            public void log(String content, Throwable t) {
                Log.d(TAG, content, t);
            }

            @Override
            public void log(String content) {
                Log.d(TAG, content);
            }
        };
        Logger.setLogger(this, newLogger);
        if (sHandler == null) {
            sHandler = new PushHandler(getApplicationContext());
        }
    }

    private boolean shouldInit() {
        ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));
        List<ActivityManager.RunningAppProcessInfo> processInfos = am.getRunningAppProcesses();
        String mainProcessName = getPackageName();
        int myPid = Process.myPid();
        for (ActivityManager.RunningAppProcessInfo info : processInfos) {
            if (info.pid == myPid && mainProcessName.equals(info.processName)) {
                return true;
            }
        }
        return false;
    }

    public static void reInitPush(Context ctx) {
        MiPushClient.registerPush(ctx.getApplicationContext(), MIPUSH_APP_ID, MIPUSH_APP_KEY);
    }

    public static PushHandler getHandler() {
        return sHandler;
    }

    public static void setMainActivity(MainActivity activity) {
        sMainActivity = activity;
    }

    public static class PushHandler extends Handler {

        private Context context;

        public PushHandler(Context context) {
            this.context = context;
        }

        @Override
        public void handleMessage(Message msg) {

            switch (msg.what) {
                case NotifyMessageReceiver.MSG_REGISTER:
                    sPushRegID = msg.obj.toString();
                    break;
                case NotifyMessageReceiver.MSG_RECEIVE_MESSAGE:
                    if (sMainActivity != null) {
                        sMainActivity.refreshMessageList();
                    }
                    break;
            }
        }
    }

    public void startLocation() {
        LogUtil.e("开始定位");
        mLocationClient.startLocation();
        isLocationSetup = true;
    }

    public void startUploadLocation(long messionID) {
        sInspectionID = messionID;
    }

    public void stopUploadLocation() {
        sInspectionID = 0;
    }

    public void stopLocation() {
        mLocationClient.stopLocation();
        isLocationSetup = false;
    }

    public boolean isLocationSetup() {
        return isLocationSetup;
    }

    public AMapLocation getLastLocation() {
        return sMapLocation;
    }

    public void startPushService() {

        if (TextUtils.isEmpty(sPushRegID)) {
            LogUtil.w("推送服务RegID为空，正在尝试重新注册");
            reInitPush(this);
            isPushServiceSetupSuccess = false;
            return;
        } else if (TextUtils.isEmpty(GlobleBean.getInstance().getUserName())) {
            LogUtil.w("推送服务必须在用户登录状态下开启");
            isPushServiceSetupSuccess = false;
            return;
        }

        Map<String, String> params = new HashMap<>();
        params.put("username", GlobleBean.getInstance().getUserName());
        params.put("regId", sPushRegID);

        HttpClient.get(this, Urls.API_SERVER_HOST + Urls.SAVE_PUSH_REGID, params,
                new HttpResponseHandler() {
                    @Override
                    public void onInnovationSuccess(JsonElement value) {
                        super.onInnovationSuccess(value);
                        isPushServiceSetupSuccess = true;
                    }

                    @Override
                    public void onInnovationFailure(String msg) {
                        super.onInnovationFailure(msg);
                        isPushServiceSetupSuccess = false;
                    }
                }, new HttpClient.NetworkUnavailableListener() {
                    @Override
                    public void networkUnavailable() {
                        isPushServiceSetupSuccess = false;
                    }
                });
    }

    public void stopPushService() {
        MiPushClient.unregisterPush(this);
        isPushServiceSetupSuccess = false;
        sPushRegID = null;
    }

    public boolean isPushServiceRunning() {
        return isPushServiceSetupSuccess;
    }

    /**
     * 初始化网络框架
     */
    private void initOkGo() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor("OkGo");
        //log打印级别，决定了log显示的详细程度
        loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY);
        //log颜色级别，决定了log在控制台显示的颜色
        loggingInterceptor.setColorLevel(Level.INFO);
        builder.addInterceptor(loggingInterceptor);
        //全局的读取超时时间
        builder.readTimeout(15 * 1000, TimeUnit.MILLISECONDS);
        //全局的写入超时时间
        builder.writeTimeout(15 * 1000, TimeUnit.MILLISECONDS);
        //全局的连接超时时间
        builder.connectTimeout(15 * 1000, TimeUnit.MILLISECONDS);
        //设置Https信任所有证书,不安全有风险
        HttpsUtils.SSLParams params = HttpsUtils.getSslSocketFactory();
        builder.sslSocketFactory(params.sSLSocketFactory, params.trustManager);
        OkGo.getInstance().init(this)                       //必须调用初始化
                .setOkHttpClient(builder.build())               //必须设置OkHttpClient
                .setCacheMode(CacheMode.FIRST_CACHE_THEN_REQUEST) //全局统一缓存模式，默认不使用缓存，可以不传
                .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE)   //全局统一缓存时间，默认永不过期，可以不传
                .setRetryCount(1);//全局统一超时重连次数，默认为三次，那么最差的情况会请求4次(一次原始请求，三次重连请求)，不需要可以设置为0
    }

    private void initLocationService() {
        //初始化定位
        mLocationClient = new AMapLocationClient(getApplicationContext());
        mLocationOption = new AMapLocationClientOption();
        //设置定位模式为AMapLocationMode.Hight_Accuracy，高精度模式。
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving);
        //设置定位间隔,单位毫秒,默认为2000ms，最低1000ms。
        mLocationOption.setInterval(60000);
        mLocationClient.setLocationOption(mLocationOption);
        //设置定位回调监听
        mLocationClient.setLocationListener(mLocationListener);
    }

    private void uploadLocation(AMapLocation aMapLocation) {

        if (sInspectionID != 0) {
            SaveTrajectoryBean bean = new SaveTrajectoryBean();
            bean.setCreatedBy(GlobleBean.getInstance().getUserName());
            bean.setLocation(String.valueOf(aMapLocation.getLongitude()) + "," + String.valueOf(aMapLocation.getLatitude()));
            bean.setMessionId(sInspectionID);

            HttpClient.post(this, Urls.API_SERVER_HOST + Urls.SAVE_TRAJECTORY, bean,
                    new HttpResponseHandler() {

                        @Override
                        public void onInnovationFailure(String msg) {
                            super.onInnovationFailure(msg);
                            Toast.makeText(mInstance, msg, Toast.LENGTH_SHORT).show();
                        }
                    }, new HttpClient.NetworkUnavailableListener() {
                        @Override
                        public void networkUnavailable() {
                            Toast.makeText(mInstance, "定位信息上报失败，请检查您的网络", Toast.LENGTH_SHORT).show();
                        }
                    });
        }

    }

    public void returnLogin() {
        Toast.makeText(this, "登录状态失效，请您重新登录", Toast.LENGTH_LONG).show();
        ActivityCache.getScreenManager().popAllActivityExceptOne(LoginActivity.class);
        startActivity(new Intent(this, LoginActivity.class));
    }

}
